package net.noday.cloudlog.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.RowMapper;

public class GeneralRowMapper<T> implements RowMapper<T> {
	private static Logger logger = Logger.getLogger(GeneralRowMapper.class);
	private Class<?> obj;
	private String objName;
	private String dbModelPrefix;

	/** @deprecated */
	public GeneralRowMapper(String objName, String dbModelPrefix) {
		this.objName = objName;
		this.dbModelPrefix = (dbModelPrefix == null ? "" : dbModelPrefix.trim());
		if ((this.dbModelPrefix.indexOf("_") < 0)
				&& (this.dbModelPrefix.length() > 0))
			this.dbModelPrefix += "_";
	}

	public GeneralRowMapper(Class obj, String dbModelPrefix) {
		setObj(obj);
		setObjName(obj.getName());
		this.dbModelPrefix = (dbModelPrefix == null ? "" : dbModelPrefix.trim());
		if ((this.dbModelPrefix.indexOf("_") < 0)
				&& (this.dbModelPrefix.length() > 0))
			this.dbModelPrefix = (this.dbModelPrefix + "_");
	}

	private Object gengeralMapRow(ResultSet rs, int num) throws SQLException,
			IllegalArgumentException, InstantiationException,
			IllegalAccessException, InvocationTargetException,
			SecurityException, NoSuchMethodException {
		Object result = null;
		HashMap validParaMap = new HashMap();
		try {
			ResultSetMetaData rsmd = rs.getMetaData();

			for (int i = 0; i < rsmd.getColumnCount(); i++) {
				validParaMap.put(strChange1(rsmd.getColumnLabel(i + 1)
						.toLowerCase()), strChange1(rsmd.getColumnName(i + 1)
						.toLowerCase()));
			}
			Class c = null;
			if ((getObj() == null) || (getObj().getName() == null))
				c = Class.forName(getObjName());
			else {
				c = Class.forName(getObj().getName());
			}

			Class[] parameterTypes = new Class[0];

			Constructor constructor = c.getConstructor(parameterTypes);

			Object[] parameters = new Object[0];

			result = constructor.newInstance(parameters);

			Field[] fields = c.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				String dbParameterName = null;
				Class type = field.getType();

				String dbType = DBUtils.getDBPreFixByParameterType(type);

				dbParameterName = strChange2(field.getName());

				dbParameterName = dbParameterName.toUpperCase();
				logger.debug(dbParameterName);

				if (validParaMap.get(field.getName()) != null)
					try {
						if (dbType.equals("C_")) {
							field.set(result, rs.getString(dbParameterName));
							continue;
						}
						if (dbType.equals("D_")) {
							field.set(result, rs.getDate(dbParameterName));
							continue;
						}
						if (dbType.equals("F_")) {
							field.set(result, Double.valueOf(rs
									.getDouble(dbParameterName)));
							continue;
						}
						if (dbType.equals("N_")) {
							field.set(result,
									Integer.valueOf(rs.getInt(dbParameterName)));
							continue;
						}
						if (dbType.equals("T_")) {
							field.set(result, rs.getTimestamp(dbParameterName));
							continue;
						}
						if (dbType.equals("B_")) {
							field.set(result, rs.getObject(dbParameterName));
							continue;
						}
						if (dbType.equals("L_")) {
							field.set(result, rs.getString(dbParameterName));
							continue;
						}
						if (dbType.equals("C_")) {
							field.set(result, rs.getString(dbParameterName));
							continue;
						}
						field.set(result, rs.getString(dbParameterName));
					} catch (IllegalArgumentException e) {
						logger.warn("[WARN-1] parameter[" + field.getName()
								+ "] of obj can not filled. "
								+ "cause of this parameter's["
								+ dbParameterName
								+ "] value can not be getted from database.");
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						logger.warn("[WARN-2] parameter[" + field.getName()
								+ "] of obj can not filled. "
								+ "cause of this parameter name's["
								+ dbParameterName
								+ "] value can not be getted from database.");
						e.printStackTrace();
					} catch (Exception e) {
						logger.warn("[WARN-3] parameter[" + field.getName()
								+ "] of obj can not filled. "
								+ "cause of this parameter name's["
								+ dbParameterName
								+ "] value can not be getted from database.");
						e.printStackTrace();
					}
				else
					logger.warn("[WARN-4] parameter[" + field.getName()
							+ "] of obj can not filled. "
							+ "cause of this parameter name's["
							+ dbParameterName
							+ "] value can not be getted from database.");
			}
		} catch (ClassNotFoundException e) {
			logger.error("[ERROR-1] objName is not valid. info is down:");
			e.printStackTrace();
		}
		return result;
	}

	public T mapRow(ResultSet arg0, int arg1) throws SQLException {
		Object result = null;
		try {
			result = gengeralMapRow(arg0, arg1);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return (T) result;
	}

	private Class<?> getObj() {
		return this.obj;
	}

	private void setObj(Class<?> obj) {
		this.obj = obj;
	}

	private String getObjName() {
		return this.objName;
	}

	private void setObjName(String objName) {
		this.objName = objName;
	}

	private String getDbModelPrefix() {
		return this.dbModelPrefix;
	}

	private void setDbModelPrefix(String dbModelPrefix) {
		this.dbModelPrefix = dbModelPrefix;
	}

	public String strChange1(String str) {
		String result = "";
		String[] a = str.toLowerCase().split("_");
		for (int i = 0; i < a.length; i++) {
			if ("".equals(a[i])) {
				continue;
			}
			a[i] = (a[i].substring(0, 1).toUpperCase() + a[i].substring(1));
			result = result + a[i];
		}

		return result;
	}

	public String strChange2(String str) {
		String result = "";

		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (i == 0) {
				String a = String.valueOf(c) + "_";
				result = result + a;
			} else if (i == 1) {
				String a = String.valueOf(c);
				result = result + a;
			} else if ((!Character.isLowerCase(c)) && (!isNumeric(c))) {
				String a = "_" + String.valueOf(c);
				result = result + a;
			} else {
				String a = String.valueOf(c);
				result = result + a;
			}
		}

		return result;
	}

	public static boolean isNumeric(char str) {
		String str1 = String.valueOf(str);
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str1);

		return isNum.matches();
	}

	public static void main(String[] args) {
		System.out.println(new GeneralRowMapper(String.class, null)
				.strChange1("C_PRO_FLAG"));
		System.out.println(isNumeric('d'));
	}

}

/*
 * Location: D:\work\tomcat\webapps\thfees\WEB-INF\classes\ Qualified Name:
 * com.doer.uitl.GeneralRowMapper JD-Core Version: 0.6.0
 */